package com.bigModel.backend.service.impl.Code;

import com.bigModel.backend.advice.result.Result;
import com.bigModel.backend.pojo.DataType;
import com.bigModel.backend.service.Device.CodeService;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

@Service
public class CodeServiceImpl implements CodeService {
    public DataType getCleaning(MultipartFile file,Integer method){
        String filePath = "D:\\clean.xlsx";
        DataType data = new DataType();
        try {
            // 保存文件到服务器的某个位置，或者进行其他处理
            File inputconvFile = new File(filePath);
            file.transferTo(inputconvFile);
            // 调用Python脚本处理文件
            cleanWithPython(inputconvFile.getAbsolutePath(),method);
            //传0重复值
            if(method==0) {
                List<List<Float>> oridata = readCSVByColumns("C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\original_data.csv");
                List<List<Float>> prodata = readCSVByColumns("C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\processed_data.csv");
                data.setOridata(oridata.get(0));
                data.setProdata(prodata.get(0));
            }//传1缺失值
            else {
                List<List<Float>> Csvdata = readCSVByColumns("C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\processed_data.csv");
                data.setOridata(Csvdata.get(0));
                data.setProdata(Csvdata.get(1));
            }
            return data;
        } catch (Exception e) {
            return null;
        }
    }

    public DataType dimreduction(MultipartFile file,Integer method){
        String filePath;
        //0PCA
        if(method==0){
            filePath = "D:\\datareduction.csv";
        }//1LLE
        else {
            filePath = "D:\\datareduction.mat";
        }
        DataType data = new DataType();
        try {
            // 保存文件到服务器的某个位置，或者进行其他处理
            File convFile = new File(filePath);
            file.transferTo(convFile);
            // 调用Python脚本处理文件
            reducectionWithPython(convFile.getAbsolutePath());
            List<List<Float>> oridata = readCSVByColumns("C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\数据降维\\data.csv");
            data.setList1(oridata.get(0));
            data.setList2(oridata.get(1));
            data.setList3(oridata.get(2));
            data.setList4(oridata.get(3));
            List<List<Float>> prodata = readCSVByColumns("C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\datareduction_d.csv");
            data.setOridata(prodata.get(0));
            data.setProdata(prodata.get(1));
            return data;
        } catch (Exception e) {
            return null;
        }
    }

    public DataType datafusion(MultipartFile file1,MultipartFile file2,MultipartFile file3){
        String filePath1,filePath2,filePath3;
        filePath1 = "D:\\modes0_s1.mat";
        filePath2 = "D:\\modes1_s1.mat";
        filePath3 = "D:\\modes2_s1.mat";
        DataType data = new DataType();
        try {
            // 保存文件到服务器的某个位置，或者进行其他处理
            File convFile1 = new File(filePath1);
            File convFile2 = new File(filePath2);
            File convFile3 = new File(filePath3);
            file1.transferTo(convFile1);
            file2.transferTo(convFile2);
            file3.transferTo(convFile3);
            // 调用Python脚本处理文件
            fusionWithPython(convFile1.getAbsolutePath(),convFile2.getAbsolutePath(),convFile3.getAbsolutePath());
            List<List<Float>> oridata = readCSVByColumns("C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\数据降维\\data.csv");
            data.setList1(oridata.get(0));
            data.setList2(oridata.get(1));
            data.setList3(oridata.get(2));
            List<List<Float>> prodata = readCSVByColumns("C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\fused_data.csv");
            data.setProdata(prodata.get(0));
            return data;
        } catch (Exception e) {
            return null;
        }
    }

    public DataType estimation(MultipartFile file){
        String filePath = "D:\\1800_0.mat";
        DataType data = new DataType();
        try {
            // 保存文件到服务器的某个位置，或者进行其他处理
            File convFile = new File(filePath);
            file.transferTo(convFile);
            // 调用Python脚本处理文件
            estimationWithPython(convFile.getAbsolutePath());
            List<List<Float>> prodata = readCSVByColumns("C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\数据估计\\预测数据\\predicted_data.csv");
            data.setProdata(prodata.get(0));
            return data;
        } catch (Exception e) {
            return null;
        }
    }

    private void cleanWithPython(String inputfilePath,Integer method) {
        ProcessBuilder pb;
        if(method==0) {
            pb = new ProcessBuilder("python", "C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\Cleaning - duplicate value removal.py", inputfilePath);
        }
        else {
            pb = new ProcessBuilder("python", "C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\Cleaning - Missing Value Handling.py", inputfilePath);
        }
        pb.redirectErrorStream(true);
        try {
            Process process = pb.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void reducectionWithPython(String filePath) {
        ProcessBuilder pb = new ProcessBuilder("python", "C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\Data_dimensionality_reduction.py", filePath);
        pb.redirectErrorStream(true);
        try {
            Process process = pb.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void fusionWithPython(String filePath1,String filePath2,String filePath3) {
        ProcessBuilder pb = new ProcessBuilder("python", "C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\Data fusion.py", filePath1,filePath2,filePath3);
        pb.redirectErrorStream(true);
        try {
            Process process = pb.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
    private void estimationWithPython(String filePath) {
        ProcessBuilder pb = new ProcessBuilder("python", "C:\\Users\\LangGuanhua\\Desktop\\guozhong\\code2\\Data estimation.py", filePath);
        pb.redirectErrorStream(true);
        try {
            Process process = pb.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static List<List<Float>> readCSVByColumns(String filePath) throws IOException {
        List<List<Float>> columns = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String headerLine = br.readLine(); // 读取并可能忽略标题行
            String line;
            while ((line = br.readLine()) != null) {
                String[] values = line.split(","); // 假设CSV使用逗号作为分隔符
                for (int i = 0; i < values.length; i++) {
                    // 去除字符串两端的空格
                    String trimmedValue = values[i].trim();

                    // 尝试将字符串转换为浮点数
                    Float floatValue = null;
                    try {
                        floatValue = Float.parseFloat(trimmedValue);
                    } catch (NumberFormatException e) {
                        // 处理转换错误，可以记录日志、抛出异常或忽略错误的值
                        System.err.println("无法将值 '" + trimmedValue + "' 转换为浮点数: " + e.getMessage());
                        // 如果你想忽略这个错误，可以继续循环或设置floatValue为某个默认值
                        // 例如：floatValue = Float.NaN; 或者 continue;
                    }

                    // 如果这是新的列，则添加新的列表
                    if (i >= columns.size()) {
                        columns.add(new ArrayList<>());
                    }

                    // 如果成功转换了浮点数，则添加到相应的列列表中
                    if (floatValue != null) {
                        columns.get(i).add(floatValue);
                    }
                }
            }
        }
        return columns;
    }

}
